package com.jic.member.controller.rest;

import com.alibaba.fastjson.JSONArray;
import com.jic.common.base.vo.RestResult;
import com.jic.common.redis.RedisClientTemplate;
import com.jic.constant.StatusConstant;
import com.jic.enums.RedisKey;
import com.jic.enums.RedisTime;
import com.jic.market.api.manage.CouponManangeApi;
import com.jic.member.controller.rest.request.LoginOutRequest;
import com.jic.member.controller.rest.request.MemberRequest;
import com.jic.member.controller.rest.request.ShareRequest;
import com.jic.member.controller.rest.request.UpdateMemberMobileByTokenRequest;
import com.jic.member.controller.rest.request.UpdateMemberPassWordByTokenRequest;
import com.jic.member.controller.rest.request.WeChatRequest;
import com.jic.member.entity.MememberUser;
import com.jic.member.request.MemberFavoriteRequest;
import com.jic.member.request.MememberUserRequest;
import com.jic.member.service.JsApiService;
import com.jic.member.service.MemberFavoriteService;
import com.jic.member.service.MememberUserInfoService;
import com.jic.member.service.MememberUserService;
import com.jic.member.sms.GenerateSmsContent;
import com.jic.member.sms.SmsOtpRequest;
import com.jic.member.sms.SmsVerifyRequest;
import com.jic.member.utils.BeanUtils;
import com.jic.member.utils.MD5Utils;
import com.jic.member.utils.SignatureUtil;
import com.jic.order.api.MemberApi;
import com.jic.product.after.api.ProductCommentApi;
import com.jic.util.GraphicHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.core.util.UuidUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @ClassName ApiController
 * @Description TODO
 * @Author zzy
 * @Date 2020/8/8 下午1:33
 */
@Slf4j
@RestController
@RequestMapping("/api/common")
@Api(value = "APi-用户基础接口", tags = "APi-用户基础接口")
public class ApiController {

    @Autowired
    RedisClientTemplate redisClientTemplate;

    @Autowired
    private GenerateSmsContent smsContent;

    @Autowired
    private MememberUserService mememberUserService;

    @Autowired
    private JsApiService jsApiService;

    @Autowired
    private MemberFavoriteService memberFavoriteService;

    @Autowired
    private ProductCommentApi productCommentRestApi;

    @Autowired
    private CouponManangeApi couponApi;

    @Autowired
    private MemberApi memberApi;

    @Resource
    private MememberUserInfoService memberUserInofo;

    @Value("${wechant.url}")
    private String url;

    @Value("${wechant.appid}")
    private String appId;


    @ApiOperation(value = " 获取图片验证码vtoken ")
    @ResponseBody
    @RequestMapping(value = "/internal/getVtoken", method = RequestMethod.GET)
    public RestResult<String> getVtoken() {
        try {
            return RestResult.success(UuidUtil.getTimeBasedUuid().toString());
        } catch (Exception e) {
            log.error("获取vtoken错误================>>>>>>>{}", e.getLocalizedMessage());
            return RestResult.error("9999", "获取vtoken异常");
        }
    }

    @ApiOperation(value = "校验图形验证码发送OTP短信")
    @ResponseBody
    @PostMapping("/internal/otp")
    public RestResult smsSendOtp(@RequestBody SmsOtpRequest request) throws Throwable {
        return smsContent.sendOtpSMS(request);
    }


    @ApiOperation(value = " 获取图片验证码 ")
    @ResponseBody
    @RequestMapping(value = "/internal/getCode", method = RequestMethod.GET)
    public void createAuthCode(@RequestParam String vtoken, HttpServletResponse response) {
        try {
            response.setHeader("content-type", "image/jpeg");
            String verifyCode = GraphicHelper.createImge(130, 36, "png", response.getOutputStream());
            // 图片验证码存放到缓存60秒
            redisClientTemplate.del(vtoken + "_IMAGE_CODE");
            redisClientTemplate.setex(vtoken + "_IMAGE_CODE", Integer.valueOf(StatusConstant.VERIFICATION_TIME.toString()), verifyCode);
        } catch (Exception e) {
            log.error("获取图片验证码异常", e);
        }
    }


    @ApiOperation(value = "账户登陆")
    @ResponseBody
    @PostMapping("/internal/memberLogin")
    public RestResult<String> memberLogin(MemberRequest memberRequest) {

        try {
            String mobile = memberRequest.getMobile();
            if (StringUtils.isEmpty(mobile)) {
                throw new Exception("账号/手机号为空");
            }
            List<MememberUser> mMembers = mememberUserService.query(new MememberUser() {{
                setPhone(mobile);
            }});

            Integer type = memberRequest.getType();

            if (CollectionUtils.isEmpty(mMembers)) {
                if (type == 0) {
                    return RestResult.error("9999", "当前用户不存在");
                }
                //验证验证码
                try {
                    SmsVerifyRequest smsVerifyRequest = new SmsVerifyRequest();
                    smsVerifyRequest.setPhone(memberRequest.getMobile());
                    smsVerifyRequest.setOtpCode(memberRequest.getCode());
                    smsContent.verify(smsVerifyRequest);
                } catch (Throwable throwable) {
                    return RestResult.error("9999", "短信验证码不正确");
                }
                //注册
                return mememberUserService.register(mobile, memberRequest.getInviteCode());

            } else {
                if (type == 0) {
                    //密码登录
                    if (StringUtils.isEmpty(memberRequest.getPassword())) {
                        return RestResult.error("9999", "登录密码不能为空");
                    }
                    if (StringUtils.isEmpty(mMembers.get(0).getPassword())) {
                        return RestResult.error("9999", "您尚未设置登录密码,只能通过验证码登录");
                    }
                    if (!MD5Utils.verify(memberRequest.getPassword(), mMembers.get(0).getSalt(), mMembers.get(0).getPassword())) {
                        return RestResult.error("9999", "登录密码错误");
                    }
                } else if (type == 1) {
                    //短信登录，验证短信验证码
                    try {
                        SmsVerifyRequest smsVerifyRequest = new SmsVerifyRequest();
                        smsVerifyRequest.setPhone(memberRequest.getMobile());
                        smsVerifyRequest.setOtpCode(memberRequest.getCode());
                        smsContent.verify(smsVerifyRequest);
                    } catch (Throwable throwable) {
                        return RestResult.error("9999", "短信验证码不正确");
                    }
                } else {
                    return RestResult.error("9999", "type类型异常");
                }
                //生成token 返回信息
                String token = UUID.randomUUID().toString();
                redisClientTemplate.setex(RedisKey.H5_LOGIN_TOKEN_.getName() + token, Integer.valueOf(RedisTime.H5_LOGIN_TIME_.getName().toString()), JSONArray.toJSONString(mMembers.get(0)));
                return RestResult.success(token);
            }
        } catch (Exception e) {
            return RestResult.error("9999", e.getLocalizedMessage());
        }
    }

    /*
     * 修改绑定的手机号
     * */
    @ApiOperation("修改绑定的手机号")
    @ResponseBody
    @PostMapping("updateMemberMobileByToken")
    public RestResult<String> updateMemberMobileByToken(@RequestBody UpdateMemberMobileByTokenRequest memberRequest) {
        try {
            String token = memberRequest.getToken();
            String memStr = redisClientTemplate.get(RedisKey.H5_LOGIN_TOKEN_.getName() + token);
            if (StringUtils.isEmpty(memStr)) {
                return RestResult.error("4000", "登录失效");
            }
            //判断验证码是否正确
            //验证验证码
            try {
                SmsVerifyRequest smsVerifyRequest = new SmsVerifyRequest();
                smsVerifyRequest.setPhone(memberRequest.getMobile());
                smsVerifyRequest.setOtpCode(memberRequest.getCode());
                smsContent.verify(smsVerifyRequest);
            } catch (Throwable throwable) {
                return RestResult.error("9999", "短信验证码不正确");
            }
            MememberUser member = JSONArray.parseObject(memStr, MememberUser.class);
            MememberUser memberVo = mememberUserService.queryByPrimaryKey(member.getId());
            Integer status = memberVo.getStatus();
            if (status == 0) {
                return RestResult.error("9999", "当前账号已注销");
            }
            //修改手机号码
            mememberUserService.update(new MememberUser() {{
                setId(memberVo.getId());
                setPhone(memberRequest.getMobile());
            }});
            return RestResult.success("修改成功");
        } catch (Exception e) {
            log.error("修改手机号错误====>>>>" + e.getLocalizedMessage());
            return RestResult.error("9999", e.getLocalizedMessage());
        }
    }


    @ApiOperation("修改登录密码")
    @ResponseBody
    @PostMapping("updateMemberPassWordByToken")
    public RestResult<String> updateMemberPassWordByToken(@RequestBody UpdateMemberPassWordByTokenRequest merReq) {
        try {

            if (StringUtils.isEmpty(merReq.getNewPassword())) {
                return RestResult.error("9999", "新密码不可为空");
            }
            if (StringUtils.isEmpty(merReq.getConfirmPassword())) {
                return RestResult.error("9999", "确认密码不可为空");
            }
            if (!merReq.getConfirmPassword().equals(merReq.getNewPassword())) {
                return RestResult.error("9999", "两次密码输入不一致");
            }
            String token = merReq.getToken();
            String memStr = redisClientTemplate.get(RedisKey.H5_LOGIN_TOKEN_.getName() + token);
            if (StringUtils.isEmpty(memStr)) {
                return RestResult.error("4000", "用户未登录");
            }
            MememberUser member = JSONArray.parseObject(memStr, MememberUser.class);
            MememberUser memberVo = mememberUserService.queryByPrimaryKey(member.getId());
            Integer status = memberVo.getStatus();
            if (status == 0) {
                return RestResult.error("9999", "当前账号已注销");
            }

            if (!merReq.getSettingPassword()) {
                memberVo.setSalt(UUID.randomUUID().toString());
            }
            //修改手机号码
            mememberUserService.update(new MememberUser() {{
                setId(memberVo.getId());
                setSalt(memberVo.getSalt());
                setPassword(MD5Utils.md5(merReq.getNewPassword(), memberVo.getSalt()));
            }});

            redisClientTemplate.del(RedisKey.H5_LOGIN_TOKEN_.getName() + token);
            return RestResult.success("登录密码修改成功");
        } catch (Exception e) {
            log.error("修改登录密码失败==============>>>" + e.getLocalizedMessage());
            return RestResult.error("9999", e.getLocalizedMessage());
        }
    }


    @ApiOperation(value = " 微信授权登录  ")
    @ResponseBody
    @RequestMapping(value = "/internal/wxLogin", method = RequestMethod.POST)
    public RestResult<Map> wxLogin(@RequestParam String code,@RequestParam String inviteCode, HttpServletResponse response) {

        String openid = null;
        Map<String, Object> weixinTokenMap = null;
        try {
            weixinTokenMap = jsApiService.getWeixinToken(code);
            openid = (String) weixinTokenMap.get("openid");

            String finalUnionid = openid;
            List<MememberUser> mMembers = mememberUserService.query(new MememberUser() {{
                setUnionId(finalUnionid);
            }});

            if (CollectionUtils.isNotEmpty(mMembers)) {
                if (mMembers.get(0).getDeleteFlag() == 1) {
                    return RestResult.error("9999", "用户被冻结，请联系管理员");
                }
                Integer status = mMembers.get(0).getStatus();
                if (status == 0) {
                    return RestResult.error("9999", "当前账号已注销");
                }
            } else {
                //注册
                Map<String, Object> finalWeixinTokenMap = weixinTokenMap;
                mMembers.add(new MememberUser() {{
                    setUnionId(finalUnionid);
                    setStatus(1);
                    setDeleteFlag(0);
                    setHeadImage(finalWeixinTokenMap.get("headimgurl").toString());
                    setNickName(finalWeixinTokenMap.get("nickname").toString());
                    setSex(Integer.valueOf(finalWeixinTokenMap.get("sex").toString()));
                    setInvitationCode(SignatureUtil.generateWord());
                }});
                List<MememberUser> mememberUserList = mememberUserService.query(new MememberUser() {{
                    setInvitationCode(inviteCode);
                    setDeleteFlag(0);
                }});
                if (CollectionUtils.isNotEmpty(mememberUserList)) {
                    mMembers.get(0).setAllocationPid(mememberUserList.get(0).getId());
                }
                mememberUserService.insert(mMembers.get(0));
            }

            String token = UUID.randomUUID().toString();
            redisClientTemplate.setex(RedisKey.H5_LOGIN_TOKEN_.getName() + token, Integer.valueOf(RedisTime.H5_LOGIN_TIME_.getName().toString()), JSONArray.toJSONString(mMembers.get(0)));

            weixinTokenMap.put("token", token);
            weixinTokenMap.put("openId", finalUnionid);
            log.info("weixinTokenMap============>:{}", weixinTokenMap);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
        }
        return RestResult.success(weixinTokenMap);
    }



    @ApiOperation(value = "微信授权登录2")
    @ResponseBody
    @RequestMapping(value = "/internal/wxLogin2", method = RequestMethod.POST)
    public RestResult<Map> wxLogin2(@RequestBody WeChatRequest request) {

        if (StringUtils.isEmpty(request.getCode())){
            return RestResult.error("9999","code为空");
        }
//        if (StringUtils.isEmpty(request.getInviteCode())){
//            return RestResult.error("9999","邀请码为空");
//        }
        String openid = null;
        Map<String, Object> weixinTokenMap = null;
        try {
            weixinTokenMap = jsApiService.getMiniProgramToken(request.getCode());
            openid = (String) weixinTokenMap.get("openId");

            String finalUnionid = openid;
            List<MememberUser> mMembers = mememberUserService.query(new MememberUser() {{
                setUnionId(finalUnionid);
            }});

            if (CollectionUtils.isNotEmpty(mMembers)) {
                if (mMembers.get(0).getDeleteFlag() == 1) {
                    return RestResult.error("9999", "用户被冻结，请联系管理员");
                }
                Integer status = mMembers.get(0).getStatus();
                if (status == 0) {
                    return RestResult.error("9999", "当前账号已注销");
                }
                String token = UUID.randomUUID().toString();
                redisClientTemplate.setex(RedisKey.H5_LOGIN_TOKEN_.getName() + token, Integer.valueOf(RedisTime.H5_LOGIN_TIME_.getName().toString()), JSONArray.toJSONString(mMembers.get(0)));
                weixinTokenMap.put("token" ,token);
                weixinTokenMap.put("openId", finalUnionid);
                weixinTokenMap.put("nickName", mMembers.get(0).getNickName());
                weixinTokenMap.put("avatar", mMembers.get(0).getHeadImage());

                mMembers.get(0).setWxImage(request.getAvatar());
                mMembers.get(0).setWxName(request.getNickName());
                mememberUserService.insert(mMembers.get(0));
            } else {
                if(StringUtils.isNotEmpty(request.getNickName())){
                    //注册
                    mMembers.add(new MememberUser() {{
                        setUnionId(finalUnionid);
                        setStatus(1);
                        setDeleteFlag(0);
                        setHeadImage(request.getAvatar());
                        setNickName(request.getNickName());
//                    setSex(Integer.valueOf(finalWeixinTokenMap.get("sex").toString()));
                        setInvitationCode(SignatureUtil.generateWord());
                    }});
                    List<MememberUser> mememberUserList = mememberUserService.query(new MememberUser() {{
                        setInvitationCode(request.getInviteCode());
                        setDeleteFlag(0);
                    }});
                    if (CollectionUtils.isNotEmpty(mememberUserList)) {
                        mMembers.get(0).setAllocationPid(mememberUserList.get(0).getId());
                    }
                    mMembers.get(0).setWxImage(request.getAvatar());
                    mMembers.get(0).setWxName(request.getNickName());
                    mememberUserService.insert(mMembers.get(0));
                    String token = UUID.randomUUID().toString();
                    redisClientTemplate.setex(RedisKey.H5_LOGIN_TOKEN_.getName() + token, Integer.valueOf(RedisTime.H5_LOGIN_TIME_.getName().toString()), JSONArray.toJSONString(mMembers.get(0)));
                    weixinTokenMap.put("token" ,token);
                    weixinTokenMap.put("openId", finalUnionid);
                }
            }

            log.info("weixinTokenMap============>:{}", weixinTokenMap);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            return RestResult.error("8888","登录异常");
        }
        return RestResult.success(weixinTokenMap);
    }


    @ApiOperation(value = "查询个人信息")
    @ResponseBody
    @PostMapping("/myInformation")
    public RestResult<Map<String, Object>> myInformation(@RequestBody MemberRequest memberRequest) {
        try {
            long myInfoBegin = System.currentTimeMillis();
            String token = memberRequest.getToken();
            String userStr = redisClientTemplate.get(RedisKey.H5_LOGIN_TOKEN_.getName() + token);
            if (StringUtils.isEmpty(userStr)) {
                return RestResult.error("4000", "登录失效");
            }
            MememberUser mMember = JSONArray.parseObject(userStr, MememberUser.class);

            MememberUser mMemberVo = mememberUserService.queryByPrimaryKey(mMember.getId());
            Map<String, Object> res = BeanUtils.beanToMap(mMemberVo);
            //查询关注
            long productCollectionNumber = memberFavoriteService.queryPageCount(new MemberFavoriteRequest() {{
                setMemberId(mMemberVo.getId());
                setEntityType(1);
            }});
            long followStoresNumber = memberFavoriteService.queryPageCount(new MemberFavoriteRequest() {{
                setMemberId(mMemberVo.getId());
                setEntityType(2);
            }});

            //我的评论
            RestResult<Long> productCommentCount = productCommentRestApi.getProductCommentCount(memberRequest.getToken());

            res.put("commentNumber", productCommentCount.getData());
            res.put("productCollectionNumber", productCollectionNumber);
            res.put("followStoresNumber", followStoresNumber);
            //查询订单数
//            RestResult<FrontOrderStatusCountInfo> frontOrderStatusCountInfoRestResult = memberApi.queryMyOrderStatusCount(mMemberVo.getId());
//
//            FrontOrderStatusCountInfo frontOrderStatusCountInfo = frontOrderStatusCountInfoRestResult.getData();
//
//            //查询我的拼团与我的优惠卷
//            RestResult<CouponNumAndGrouponNumResponse> myCoupon = couponApi.queryMyCouponNumberAndGrouponNumber(new CouponNumAndGrouponNumRequest() {{
//                setUserId(mMemberVo.getId());
//            }});
//            res.put("couponNumber", myCoupon.getData().getCouponNum());
//            res.put("fightNumber", myCoupon.getData().getGrouponNum());
//
//            res.put("orderNumberList", new HashMap<String, Integer>() {{
//                put("pendingPaymentNumber", frontOrderStatusCountInfo == null ? 0 : frontOrderStatusCountInfo.getWaitPayCount());//待付款
//                put("deliveredNumber", frontOrderStatusCountInfo == null ? 0 : frontOrderStatusCountInfo.getWaitShipCount());//待发货
//                put("signNumber", frontOrderStatusCountInfo == null ? 0 : frontOrderStatusCountInfo.getAlreadyShipCount());//已签收
//                put("commentNumber", frontOrderStatusCountInfo == null ? 0 : frontOrderStatusCountInfo.getWaitReviewCount());//待评价
//                put("refund", frontOrderStatusCountInfo == null ? 0 : frontOrderStatusCountInfo.getAfterSaleCount());//退款/售后
//            }});

            long myInfoEnd = System.currentTimeMillis();
            log.debug("myInformation member Query MyInfo End,Result Info:" + res + " 耗时：" + (myInfoEnd - myInfoBegin));
            return RestResult.success(res);
        } catch (Exception e) {

            return RestResult.error("9999", e.getLocalizedMessage());
        }
    }


    @ApiOperation(value = " 退出登录 ")
    @ResponseBody
    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    public RestResult<Boolean> loginOut(@RequestBody LoginOutRequest request) {
        redisClientTemplate.del(RedisKey.H5_LOGIN_TOKEN_.getName() + request.getToken());
        return RestResult.success(true);
    }

    /**
     * 初始化微信JSSDK配置信息
     *
     * @param request 分享地址
     * @return
     * @throws Exception
     */
    @PostMapping("/initWXJSSDKConfigInfo")
    @ResponseBody
    public RestResult<Map> initWXJSConfig(@RequestBody ShareRequest request) throws Exception {
        return RestResult.success(jsApiService.getWeiXinApiSign(request.getShareUrl()));
    }

    @GetMapping("/authorize")
    @ApiOperation(value = "微信制授权登录")
    public void authorize(HttpServletResponse response, @RequestParam("returnUrl") String returnUrl) throws IOException {
        log.info("returnUrl：{}", returnUrl);
        String encoderUrl = URLEncoder.encode(returnUrl, "UTF-8");
        log.info("encoderUrl：{}", encoderUrl);
        String redirectUri = url + "/jic-member/api/common/internal/wxLogin";
        // 按照文档要求拼接访问地址
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                + appId
                + "&redirect_uri="
                + redirectUri
                + "&response_type=code&scope=snsapi_userinfo&state=" + encoderUrl + "&connect_redirect=1#wechat_redirect";
        log.info("redirectUrl={}", url);
        response.sendRedirect(url);// 跳转到要访问的地址;
//        return RestResult.success(url);
    }

    @PostMapping("/queryMemberInfo")
    @ApiOperation(value = "查询个人详细信息")
    @ResponseBody
    public RestResult<MememberUser> queryMemberInfo(@RequestBody MemberRequest memberRequest){
        String token = memberRequest.getToken();
        String userStr = redisClientTemplate.get(RedisKey.H5_LOGIN_TOKEN_.getName() + token);
        if (StringUtils.isEmpty(userStr)) {
            return RestResult.error("4000", "登录失效");
        }
        MememberUser mMember = JSONArray.parseObject(userStr, MememberUser.class);

        MememberUser mMemberVo = mememberUserService.queryByPrimaryKey(mMember.getId());
        return RestResult.success(mMemberVo);
    }

    @ApiOperation(value = "修改用户信息")
    @ResponseBody
    @PostMapping("/updateMemberInfo")
    public RestResult<String> updateMemberInfo(@RequestBody MememberUserRequest mememberUserRequest) {
        return memberUserInofo.updateMemberInfo(mememberUserRequest);
    }

}
